package com.yuzhihao.writejvm.attributes.runtimevta;

import com.yuzhihao.writejvm.clazz.ClassInfo;
import com.yuzhihao.writejvm.read.Parse;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.log4j.Log4j2;

import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * The items of the target_info union (except for the first) specify precisely which type in a declaration or expression is annotated.
 * <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.20.1">LocalvarTarget</a>
 *
 * @author yzh
 * @since 2021年12月11日17:05:51
 */
@Data
@Log4j2
@EqualsAndHashCode(callSuper = true)
public class LocalvarTarget extends TypeAnnotation {

    private int table_length_u2 = 2;

    private int table_length;

    private List<Table> tables = new ArrayList<>();

    public LocalvarTarget(int tag){
        super();
        super.setTarget_type(tag);
    }

    @Override
    public void parse(DataInputStream dis, ClassInfo ci) {

        try {
            this.table_length = Parse.byteToInt(this.table_length_u2, dis);

            int i = 0;
            while (i < this.table_length){
                Table table = new Table();
                table.parse(dis,ci);
                this.tables.add(table);
                i++;
            }

            super.parse(dis, ci);
        } catch (IOException e) {
            log.error(e);
        }

    }

    @Data
    @Log4j2
    public static class Table implements Parse{
        private int start_pc_u2 = 2;
        private int start_pc;

        private int length_u2 = 2;
        private int length;

        private int index_u2 = 2;
        private int index;

        @Override
        public void parse(DataInputStream dis, ClassInfo ci) {
            try {
                this.start_pc = Parse.byteToInt(this.start_pc_u2,dis);
                this.length = Parse.byteToInt(this.length_u2,dis);
                this.index = Parse.byteToInt(this.index_u2,dis);
            } catch (IOException e) {
                log.error(e);
            }
        }
    }
}
